# coding=utf-8
import datetime
import json
import os
import shutil
import subprocess
import sys
import time
import webbrowser


class AllureReport:
    def __init__(self):
        # 获得当前时间
        self.report_out = "report_" + datetime.datetime.now().strftime("%Y_%m_%d_%H_%M_%S")
        self.results = "results"
        self.report_title = "Allure Report"
        self.report_language = "zh-cn"
        self._add_environment_information()

    # 生成报告
    def generate_report(self):
        # allure generate 命令，固定的
        # ./report_time 是生成的 Allure 测试报告的输出路径。
        # -o 输出output
        # ./report 生成的allure报告的路径
        # --clean 清空
        # ./result 测试结果数据（通常是 JSON 文件）所在的路径
        # os.system("allure generate {} -o {} --clean --language {}"
        #           .format(self.results, self.report_out, self.report_language))
        os.system("allure generate {} -o {} --clean"
                  .format(self.results, self.report_out))
        # # 执行Allure报告生成命令
        # command = "allure generate {} -o {} --clean".format(self.results, self.report_out)
        # subprocess.run(command, shell=True)
        self._set_windows_title()
        self._set_report_title()
        self._history()
        self._set_web_tab_icon()
        self.open_report()

    def _set_web_tab_icon(self):
        if os.path.exists("src/main/res/favicon.ico"):
            shutil.copy("src/main/res/favicon.ico", self.report_out)

    def open_report(self):
        shutil.copy("打开测试报告.bat", self.report_out)
        # 自动打开测试报告会显示异常
        try:
            # 切换到 bat 文件所在目录
            os.chdir(self.report_out)
            # 使用 subprocess.run 运行 bat 脚本
            result = subprocess.run(["打开测试报告.bat"], shell=True, capture_output=True, text=True)
            if result.returncode == 0:
                print("Batch script executed successfully.")
                print("Output:", result.stdout)
            else:
                print("Batch script failed.")
                print("Error:", result.stderr)
        except Exception as e:
            print(f"An error occurred: {e}")

    def open_report(self):
        os.system("allure serve {}".format(self.results))
        # time.sleep(10)  # 可根据实际情况调整等待时间
        # # 打开生成的报告
        # server_process = subprocess.Popen("allure open {}".format(self.report_out), shell=True)
        # # 等待一段时间，让服务器启动完毕
        # time.sleep(3)  # 可根据实际情况调整等待时间
        # # 终止服务器进程
        # server_process.terminate()

    # 设置报告窗口的标题
    def _set_windows_title(self):
        """  设置打开的 Allure 报告的浏览器窗口标题文案
        @param new_title:  需要更改的标题文案 【 原文案为：Allure Report 】
        @return: 没有返回内容，调用此方法传入需要更改的文案即可修改窗体标题文案
        """
        # report_title_filepath：这里是测试报告HTML标题的相对路径
        report_title_filepath = "{}/index.html".format(self.report_out)
        # 定义为只读模型，并定义名称为: f
        with open(report_title_filepath, 'r+', encoding="utf-8") as f:
            # 读取当前文件的所有内容
            all_the_lines = f.readlines()
            f.seek(0)
            f.truncate()
            # 循环遍历每一行的内容，将 "Allure Report" 全部替换为 → new_title(新文案)
            for line in all_the_lines:
                f.write(line.replace("Allure Report", self.report_title))
            # 关闭文件
            f.close()

    def _set_report_title(self):
        # 自定义测试报告标题
        # summary.json：这里是测试报告标题的相对路径，测试报告文案获取的文件地址
        title_filepath = "{}/widgets/summary.json".format(self.report_out)
        self._write_json_data(title_filepath, self.report_title)

    # 获取 summary.json 文件的数据内容
    def _get_json_data(self, title_filepath, name):
        # 定义为只读模型，并定义名称为f
        with open(title_filepath, 'rb') as file:
            # 加载json文件中的内容给params
            params = json.load(file)
            # 修改内容
            params['reportName'] = name
        return params

    # 报告标题写入json文件
    def _write_json_data(self, title_filepath, name):
        data = self._get_json_data(title_filepath, name)
        # 定义为写模式，名称定义为r
        with open(title_filepath, 'w', encoding="utf-8") as file:
            # 将dict写入名称为r的文件中
            json.dump(data, file, ensure_ascii=False, indent=4)

    # 添加环境信息
    """
        environment.properties文件格式：
        Browser = Chrome
        Browser.Version = 63.0
        Stand = Production
        乱码：  .encode("unicode_escape").decode()
    """
    def _add_environment_information(self):
        if not os.path.exists("{}".format(self.results)):
            os.mkdir("{}".format(self.results))
        if os.path.exists("environment.properties"):
            # 复制 environment.properties 文件到 self.results 目录下
            shutil.copy("environment.properties", self.results)

    def add_environment_information(self, driver):
        try:
            if not os.path.exists("{}".format(self.results)):
                os.mkdir("{}".format(self.results))
            # 获取浏览器名称
            driver_name = driver.get_driver_name()
            # 获取浏览器版本
            driver_version = driver.get_driver_version()
            # 获取操作系统信息
            os_name = os.name
            # 获取 Python 版本
            python_version = sys.version
            # 获取当前工作目录
            cwd = os.getcwd()
            # 假设环境为 Production，可根据实际情况修改
            environment = "Production"
            # 使用 os.path.join 构建文件路径
            env_file_path = os.path.join(self.results, "environment.properties")
            with open(env_file_path, "w", encoding="utf-8") as env_file:
                # 写入浏览器信息
                env_file.write(f"Browser={driver_name}\n")
                # 写入浏览器版本信息
                env_file.write(f"Browser.Version={driver_version}\n")
                # 写入操作系统信息
                env_file.write(f"OS={os_name}\n")
                # 写入 Python 版本信息
                env_file.write(f"Python.Version={python_version}\n")
                # 写入当前工作目录信息
                env_file.write(f"Working.Directory={cwd}\n")
                # 写入环境信息
                env_file.write(f"Stand={environment}\n")
        except AttributeError:
            print("The driver object does not have the required methods.")
        except Exception as e:
            print(f"An error occurred while adding environment information: {e}")

    # 文件夹复制到另一个文件夹
    def _copy_file(self, path):
        for subdirectory in os.listdir(path):
            # 拼接路径
            full_dir = os.path.join(path, subdirectory)
            # 复制文件
            if os.path.isfile(full_dir):
                shutil.copy(full_dir, "{}/history".format(self.results))
            # 递归目录
            if os.path.isdir(full_dir):
               self._copy_file(full_dir)

    # 趋势
    # 将report下的history放到results下
    def _history(self):
        if not os.path.exists("{}/history".format(self.results)):
            os.mkdir("{}/history".format(self.results))
        files_path = os.listdir("./")
        history_path = []
        for file_path in files_path:
            if file_path[:7] == "report_":
                history_path.append(file_path)
        if history_path:
            self._copy_file("{}/history".format(history_path[-1]))

